import os
import sys
import threading
from http.server import SimpleHTTPRequestHandler, HTTPServer
from PIL import Image
import urllib.parse
import msvcrt  # 仅限Windows，按键监听
import io

class CustomHandler(SimpleHTTPRequestHandler):

    THUMBNAIL_SIZE = (100, 100)  # 定义缩略图的最大尺寸

    def do_GET(self):
        if self.path.startswith('/thumbnails/'):
            original_path = self.path[len('/thumbnails/'):]
            self.send_thumbnail(original_path)
        else:
            super().do_GET()

    def send_thumbnail(self, filepath):
        # 解码路径，并构造完整路径
        decoded_path = urllib.parse.unquote(filepath)
        full_path = os.path.join(os.getcwd(), decoded_path)

        if not os.path.isfile(full_path):
            self.send_error(404, "File not found")
            return
        
        try:
            with Image.open(full_path) as img:
                img.thumbnail(self.THUMBNAIL_SIZE)
                img_byte_arr = io.BytesIO()
                img.save(img_byte_arr, format='JPEG')
                img_byte_arr.seek(0)

                # 设置响应头并发送图像数据
                self.send_response(200)
                self.send_header("Content-type", "image/jpeg")
                self.end_headers()
                self.wfile.write(img_byte_arr.getvalue())
        except Exception as e:
            self.send_error(500, f"Error generating thumbnail: {e}")

    def list_directory(self, path):
        try:
            entries = os.listdir(path)
        except OSError:
            self.send_error(404, "No permission to list directory")
            return None

        html = f"""
        <html>
        <head>
            <meta charset="UTF-8">
            <title>Directory listing for {path}</title>
            <style>
                body {{
                    font-family: Arial, sans-serif;
                }}
                ul {{
                    list-style-type: none;
                    padding: 0;
                    display: flex;
                    flex-wrap: wrap;
                }}
                li {{
                    margin: 10px;
                    text-align: center;
                }}
                img {{
                    max-height: 100px; /* 控制缩略图高度 */
                    border: 1px solid #ccc; 
                    border-radius: 4px; 
                }}
            </style>
        </head>
        <body>
            <h2>Directory listing</h2>
            <ul>
        """

        for entry in entries:
            full_path = os.path.join(path, entry)
            URL_path = urllib.parse.quote(full_path)

            if os.path.isdir(full_path):
                html += f'<li><a href="{URL_path}/">{entry}/</a></li>'
            elif entry.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
                thumbnail_url = f"/thumbnails/{URL_path}"
                html += f'''
                <li>
                    <img src="{thumbnail_url}" alt="{entry}"/>
                    <br>{entry}
                </li>'''
            else:
                html += f'<li><a href="{URL_path}">{entry}</a></li>'

        html += """
            </ul>
        </body>
        </html>
        """
        
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=utf-8")  # 设置字符集为UTF-8
        self.end_headers()
        self.wfile.write(html.encode('utf-8'))  # 使用UTF-8编码写入响应内容

def run_server(port):
    server_address = ('', port)
    httpd = HTTPServer(server_address, CustomHandler)
    
    print(f"Starting HTTP server on port {port}...")
    httpd.serve_forever()

def find_available_port(start_port):
    port = start_port
    while True:
        try:
            server = HTTPServer(('', port), CustomHandler)
            server.socket.close()  # 关闭服务器的socket以测试该端口是否可用
            return port
        except OSError:
            port += 1

def listen_for_exit():
    """等待ESC键按下以退出程序"""
    print("Press ESC to exit the program.")
    while True:
        if msvcrt.kbhit() and msvcrt.getch() == b'\x1b':  # ESC键是ASCII码27（0x1b）
            print("Exiting...")
            os._exit(0) 

if __name__ == "__main__":
    start_port = 8000
    available_port = find_available_port(start_port)

    server_thread = threading.Thread(target=run_server, args=(available_port,))
    server_thread.daemon = True   # 设置为daemon线程，使其在主线程结束时自动退出
    server_thread.start()

    # 启动监听ESC键的线程
    listen_for_exit()
